﻿(function($, XS){

    function Report() {
        this.cookieKey = 'active_restaurant_id';
        this.restaurantList = null;
        this.footMenu = null;
        this.storeId = null;
        this.type = 'today'; // history
        this.body = {
            today: null,
            history: null
        };
        this.dateChooser = null;
        this.dateFormat = 'YYYY-MM-DD';
        this.dateRange = { from: new Date(), to: new Date(), mode: 'days'};
        this.leftMenuToggle = null;
    }

    $.extend(Report.prototype, {
        init: function() {
            this.body = {
                today: $('.report-today'),
                history: $('.report-history')
            };
            var _this = this;
            this.loadRestaurantList(function(){
                XS.util.menuActive($('.restaurant-list > li'), {
                    cookie: _this.cookieKey,
                    callback: function (menu) {
                        var $menu = $(menu);
                        var id = $menu.attr('data-value');
                        if (id != '') {
                            _this.storeId = id;
                            var restaurantName = $menu.find('.title').text();
                            $('.navbar-brand').text(restaurantName);
                            _this.loadCurrentStatusData();
                            _this.leftMenuToggle && _this.leftMenuToggle.toggle();
                        } else {
                            XS.util.alert('加载门店失败，请重试！');
                        }
                    }
                });
                _this.initFootMenu();
            });
            this.initLeftMenuToggle();
        },
        initLeftMenuToggle: function() {
            var _this = this;
            this.leftMenuToggle = XS.util.mainMenuToggle(function(target, show){
                if (show && !$('.user-info').hasClass('loaded') ) {
                    _this.loadUserInfo();
                }
            });
        },
        initFootMenu: function() {
            var _this = this;
            XS.util.menuActive($('.foot-menu'), {
                callback: function (menu) {
                    _this.type = $(menu).attr('data-type');
                    _this.loadCurrentStatusData();
                }
            });
        },
        loadCurrentStatusData: function() {
            $('.report-main').hide();
            this.body[this.type].show();
            if ('today' == this.type) {
                this.loadLatestRealTimeSummary();
            } else if ('history' == this.type) {
                if (!this.dateChooser) {
                    this.dateChooser = XS.dateChooser();
                    this.dateChooser.init();
                } else {
                    this.dateChooser.changeDate(0);
                }
            }
        },
        loadLatestRealTimeSummary: function(){
            var _this = this;
            // this.updateReportTitle('今日');
            this.loadStart();
            XS.ajax.doRequest({
                url: '/Report/LatestRealTimeSummary',
                data: {storeId: this.storeId },
                success: function(result){
                    _this.renderLatestRealTimeSummary(result.data || {});
                }
            });
        },
        renderLatestRealTimeSummary: function(data) {
            this.loadCompleted();

            var businessData = data['BusinessData'] || {};
            this.renderBlock('Amount', this.convertSettleData(businessData, '营业额', 'Amount', true));
            this.renderBlock('BillQuantity', this.convertSettleData(businessData, '账单数', 'BillQuantity', false));
            this.renderBlock('CustomerQuantity', this.convertSettleData(businessData, '人数', 'CustomerQuantity', false));
            this.renderBlock('IdleTableQuantity', {title: '空闲台', primary: businessData['IdleTableQuantity'] || 0, secondary: '个'});

            var paymentHeaders = [
                {name: '名称', key: 'SubjectName', type: 'text', visible: true},
                {name: '编号', key: 'SubjectNo', type: 'text', visible: false},
                {name: '金额', key: 'Amount', type: 'amount', visible: true},
                {name: '单数', key: 'Quantity', type: 'number', visible: true}
            ];
            this.addTable('PaymentSummary', '支付方式', paymentHeaders, data);

            var tableGroupHeaders = [
                {name: '类别', key: 'TableGroupName', type: 'text', visible: true},
                {name: '编号', key: 'TableGroupNo', type: 'text', visible: false},
                {name: '空闲', key: 'IdleTableQuantity', type: 'number', visible: true},
                {name: '总数', key: 'TotalTableQuantity', type: 'number', visible: true}
            ];
            this.addTable('TableGroupInfo', '桌台', tableGroupHeaders, data);

            var vipDealHeaders = [
                {name: '类型', key: 'ActionName', type: 'text', visible: true},
                {name: '编号', key: 'ActionNo', type: 'text', visible: false},
                {name: '笔数', key: 'Quantity', type: 'number', visible: true},
                {name: '储值', key: 'StoredValue', type: 'amount', visible: true},
                {name: '返利', key: 'RebateValue', type: 'amount', visible: true},
                {name: '积分', key: 'CreditValue', type: 'number', visible: true}
            ];
            this.addTable('VIPDealSummary', '会员交易', vipDealHeaders, data);

            var lastTime = data['CreateTime'] || '';
            this.renderById('CreateTime', '更新于 ' + lastTime);
        },
        loadHistoryReports: function(startDate, endDate, mode) {
            this.updateReportTitle(dateRangeToString(startDate, endDate, mode));
            this.loadStart();
            this.loadHistoryBillSummary(startDate.format(this.dateFormat), endDate.format(this.dateFormat));
        },
        loadHistoryBillSummary: function(startDate, endDate){
            var _this = this;
            XS.ajax.doRequest({
                url: '/Report/HistoryBillSummary',
                data: {storeId: this.storeId, startDate: startDate, endDate: endDate },
                success: function(result){
                    _this.renderHistoryBillSummary(startDate, endDate, result.data || {});
                }
            });
        },
        renderHistoryBillSummary: function(startDate, endDate, data) {
            this.loadCompleted();
            var quantity = parseInt(data['BillQuantity']) || 0;
            var customer = parseInt(data['CustomerQuantity']) || 0;
            var invoiceAmount = parseInt(data['InvoiceAmount']) || 0;
            var actualAmount = parseInt(data['RealIncomeAmount']) || 0;
            var shouldAmount = parseInt(data['ReceivableAmount']) || 0;
            this.renderBlock('Amount', {title: '营业额', primary: XS.util.toAmount(shouldAmount, '￥'), secondary: '实收 ' + XS.util.toAmount(actualAmount, '￥')});
            this.renderBlock('InvoiceAmount', {title: '发票额', primary: XS.util.toAmount(invoiceAmount, '￥')});
            this.renderBlock('BillQuantity', {title: '账单数', primary: quantity, secondary: '单'});
            this.renderBlock('CustomerQuantity', {title: '人数', primary: customer, secondary: '人'});
            if (shouldAmount > 0) {
                this.loadHistoryData(startDate, endDate);
            } else {
                $('.report-table').empty().hide();
            }
        },
        loadHistoryData: function(startDate, endDate) {
            this.loadHistoryTableData('HistoryPaymentSummary', startDate, endDate);
            this.loadHistoryTableData('HistoryVipDealSummary', startDate, endDate);
            this.loadHistoryTableData('HistoryDepartmentIncomeSummary', startDate, endDate);
            this.loadHistoryTableData('SalesRanking', startDate, endDate);
        },
        loadHistoryTableData: function(id, startDate, endDate){
            var _this = this;
            XS.ajax.doRequest({
                url: '/Report/' + id,
                data: {storeId: this.storeId, startDate: startDate, endDate: endDate },
                success: function(result) {
                    _this.renderHistoryTableData(id, result.data || []);
                }
            });
        },
        renderHistoryTableData: function(id, data) {
            var title = '';
            var headers = [];

            if (id == 'HistoryPaymentSummary') {
                title = '支付方式';
                headers = [
                    {name: '名称', key: 'SubjectName', type: 'text', visible: true},
                    {name: '编号', key: 'SubjectNo', type: 'text', visible: false},
                    {name: '金额', key: 'Amount', type: 'amount', visible: true},
                    {name: '账单数', key: 'Quantity', type: 'number', visible: true}
                ];
            } else if (id == 'HistoryVipDealSummary') {
                title = '会员交易';
                headers = [
                    {name: '交易类型', key: 'ActionName', type: 'text', visible: true},
                    {name: '编号', key: 'ActionNo', type: 'text', visible: false},
                    {name: '账单数', key: 'Quantity', type: 'number', visible: false},
                    {name: '储值', key: 'StoredValue', type: 'amount', visible: true},
                    {name: '返利', key: 'RebateValue', type: 'amount', visible: true},
                    {name: '积分', key: 'CreditValue', type: 'number', visible: true}
                ];
            } else if (id == 'HistoryDepartmentIncomeSummary') {
                title = '营业收入';
                headers = [
                    {name: '名称', key: 'SubjectName', type: 'text', visible: true},
                    {name: '编号', key: 'SubjectNo', type: 'text', visible: false},
                    {name: '金额', key: 'Amount', type: 'amount', visible: true}
                ];
            } else if (id == 'SalesRanking') {
                title = '销售排行';
                headers = [
                    {name: '序号', key: 'Sort', type: 'text', visible: true},
                    {name: '部门', key: 'DepartmentName', type: 'text', visible: false},
                    {name: '商品', key: 'DishName', type: 'text', visible: true},
                    {name: '销售金额', key: 'SaleAmount', type: 'amount', visible: true},
                    {name: '销售数量', key: 'SaleQuantity', type: 'number', visible: true}
                ];
            }
            this.addTable(id, title, headers, data, {dataConverted: true, addColSpan: { enabled: true, key: 'Sort', condition: '1', targetKey: 'DepartmentName'}});
        },
        loadUserInfo: function(){
            var _this = this;
            XS.ajax.doRequest({
                url: '/api/Common/UserInfo',
                success: function(result){
                    _this.renderUserInfo(result.data);
                }
            });
        },
        renderUserInfo: function(data) {
            var $userInfo = $('.user-info');
            $userInfo.addClass('loaded');

            var headPicture = data['HeadPicture'];
            var $img = $('<img/>').attr({'src': headPicture});
            $userInfo.find('.head-picture').append($img);

            var nickname = data['NickName'] || '获取失败';
            $userInfo.find('.nickname').html(nickname);
        },
        loadRestaurantList: function(callback){
            var _this = this;
            XS.ajax.doRequest({
                url: '/api/Common/MyStore',
                success: function(result){
                    _this.renderRestaurantList(result.data);
                    callback && callback();
                }
            });
        },
        removeStore: function(el){
            var $el = $(el).closest('li');
            var id = $el.attr('data-value'), name = $el.attr('data-label');
            if (!confirm('请确定是否要取消关注 ' + name + '？')) return;
            XS.ajax.doRequest({
                url: '/api/Common/RemoveStoreAuthorize',
                data: {storeId: id},
                success: function(result){
                    location.reload();
                }
            });
        },
        renderRestaurantList: function(data) {
            var $restaurantList = $('.restaurant-list');
            $restaurantList.empty();
            for (var i in data) {
                var restaurant = data[i];
                var id = restaurant['Id'];
                var name = restaurant['Name'];
                var $restaurant = $('<li></li>').attr({'data-value': id, 'data-label': name});
                var $title = $('<span class="title"></span>').text(name);
                var $remove = $('<span class="remove">&times;</span>');
                $restaurant.append($title, $remove);
                $restaurantList.append($restaurant);
            }
            var _this = this;
            $restaurantList.find('.remove').bind('click', function(e){
                e.preventDefault();
                e.stopPropagation();
                _this.removeStore(this);
            });
        },
        renderBlock: function(id, data) {
            var $block = $('<div class="report-data-block"></div>');
            if (data.title !== undefined) {
                var $title = $('<div class="report-data-title"></div>').html(data.title);
                $block.append($title);
            }
            if (data.primary !== undefined) {
                var $primary = $('<div class="report-data-primary"></div>').html(data.primary);
                if (data.secondary !== undefined) {
                    var $secondary = $('<span class="report-data-secondary"></span>').html(data.secondary);
                    $primary.append($secondary);
                }
                $block.append($primary);
            }
            this.findById(id).html($block);
        },
        addTable: function(id, title, headers, data, options) {

            var items = (options !== undefined && options.dataConverted) ? data : (data[id] || []);
            var addColSpan = options !== undefined ? options.addColSpan : false;

            var $box = this.findById(id);
            if (!items.length) {
                $box.hide();
                return;
            }
            $box.show();

            var $table = $('<table class="table"></table>');

            var $caption = $('<caption></caption>');
            $caption.append('<span class="report-table-title">' + title + '</span>');
            if (id == 'SalesRanking') {
                $caption.addClass('control-bar');
                var $control = $('<div class="btn-group"></div>');
                var $desc = $('<button class="btn btn-sm" data-sort="desc">畅销</button>');
                var $asc = $('<button class="btn btn-sm" data-sort="asc">滞销</button>');
                ('asc' == this.sort ? $asc : $desc).addClass('btn-primary');
                $control.append($desc, $asc);
                $caption.append($control);
                var _this = this;
                $asc.bind('click', function(){
                    _this.sort = 'asc';
                    _this.toggleSalesRanking(id);
                });
                $desc.bind('click', function(){
                    _this.sort = 'desc';
                    _this.toggleSalesRanking(id);
                });
            }
            $table.append($caption);

            var cols = 0; // 显示的列数
            var $header = $('<thead></thead>');
            var $headerTr = $('<tr></tr>');
            for (var i in headers) {
                var headItem = headers[i];
                if (headItem.visible) {
                    var name = headItem.name;
                    var $th = $('<th></th>').html(name);
                    if (headItem.type == 'number' || headItem.type == 'amount') {
                        $th.addClass('text-right');
                    }
                    $headerTr.append($th);
                    cols ++;
                }
            }
            $header.append($headerTr);
            $table.append($header);

            var $body = $('<tbody></tbody>');
            for (var j in items) {
                var bodyItem = items[j];
                if (addColSpan && addColSpan.enabled) { // 合并单元格
                    if (bodyItem[addColSpan.key] == addColSpan.condition) {
                        var $colSpanTr = $('<tr></tr>');
                        var $colSpan = $('<td></td>').attr({'colspan': cols}).html(bodyItem[addColSpan.targetKey]);
                        $colSpanTr.append($colSpan);
                        $body.append($colSpanTr);
                    }
                }
                var $bodyTr = $('<tr></tr>');
                for (var k in headers) {
                    var _headItem = headers[k];
                    if (_headItem.visible) {
                        var itemVal = bodyItem[_headItem.key];
                        if (itemVal != null) {
                            if (_headItem.type == 'amount') {
                                itemVal = XS.util.toAmount(itemVal);
                            } else if (_headItem.type == 'number') {
                                itemVal = XS.util.numberFormat(itemVal, 0);
                            }
                        }
                        var $td = $('<td></td>').html(itemVal);
                        if (_headItem.type == 'number' || _headItem.type == 'amount') {
                            $td.addClass('text-right');
                        }
                        $bodyTr.append($td);
                    }
                }
                $body.append($bodyTr);
            }
            $table.append($body);
            $box.html($table);
        },
        renderById: function(id, elem) {
            this.findById(id).html(elem);
        },
        findById: function(id) {
            return this.getBody().find('[data-id="' + id + '"]');
        },
        getBody: function() {
            return this.body[this.type].find('.report-body');
        },
        convertSettleData: function(data, title, key, isAmount) {
            var settled = data['Settled' + key] || 0;
            var unsettled = data['UnSettled' + key] || 0;
            var primary = isAmount ? XS.util.toAmount(settled, '￥') : settled;
            var secondary = '待结 ' + (isAmount ? XS.util.toAmount(unsettled, '￥') : unsettled);
            return {title: title, primary: primary, secondary: secondary};
        },
        updateReportTitle: function(date){
            var body = this.body[this.type];
            body.find('.report-date').html(date);
        },
        loadStart: function() {
            var $body = $('body');
            var $loading = $('<div class="report-data-loading"><div class="loading"></div></div>');
            $body.append($loading);
        },
        loadCompleted: function() {
            $('.report-data-loading').remove();
        },
        toggleSalesRanking: function(id) {
            var $box = this.findById(id);
            $box.empty();
            var _this = this, startDate = this.dateChooser.startDate.format(this.dateFormat), endDate = this.dateChooser.endDate.format(this.dateFormat);
            XS.ajax.doRequest({
                url: '/Report/' + id,
                data: {storeId: this.storeId, startDate: startDate, endDate: endDate, sort: _this.sort },
                success: function(result) {
                    _this.renderHistoryTableData(id, result.data || []);
                    $box[0].scrollIntoView();
                }
            });
        }
    });

    function dateRangeToString(from, to, mode) {
        var today = moment();
        var yearF = (sameYear(today, from) ? '' : 'YYYY年');
        if (sameDay(from, to) || 'days' == mode) {
            if (sameDay(today, from)) {
                return '今日';
            }
            return from.format(yearF + 'M月D日（' + ('星期' + ['日', '一', '二', '三', '四', '五', '六'][from.day()] + '）'));
        } else if ('months' == mode) {
            if (sameMonth(today, from)) {
                return '本月';
            }
            return from.format('YYYY年M月');
        } else {
            var year = (sameYear(from, to) ? '' : 'YYYY年');
            var month = (sameMonth(from, to) || sameMonth(today, from) ? '' : 'M月');
            return from.format(yearF + 'M月D日') + '到' + to.format(year + month + 'D日');
        }
    }

    function sameYear(from, to) {
        return from.year() == to.year();
    }
    function sameMonth(from, to) {
        return sameYear(from, to) && from.month() == to.month();
    }
    function sameDay(from, to) {
        return sameMonth(from, to) && from.date() == to.date();
    }

    /**
     * User: Wufan
     * Date: 15-1-28 下午4:00
     */
    window.DateChooser = function(opts){
        this.chooser = null;
        this.onDateChanged = function(oldDate, newDate){};
        this.minDate = false;
        this.maxDate = false;
        this.startDate = moment().subtract(1, 'days');
        this.endDate = moment();//.subtract(1, 'days');
        this.btnControl = null;
        this.btnPrev = null;
        this.btnNext = null;
        this.chooserMode = null;
        this.rangePicker = null;
        this.rangePickerBlock = null;
        this.dateFormat = 'YYYY-MM-DD';
        this.options = opts;
        return this;
    };
    window.DateChooser.prototype = {
        init: function() {
            var _this = this;

            this.chooser = $('.report-history > .report-head');
            this.chooser.attr({'data-mode': this.mode});

            this.chooserMode = $('.date-chooser-mode');
            this.rangePickerBlock = $('.date-range-picker');
            this.rangePicker = this.rangePickerBlock.find('.date-range-picker-event');

            this.btnControl = $('.date-btn-control');
            this.btnPrev = this.btnControl.find('.date-control-prev');
            this.btnNext = this.btnControl.find('.date-control-next');
            this.btnPrev.bind('click', function(){
                _this.changeDate(-1);
            });
            this.btnNext.bind('click', function(){
                _this.changeDate(1);
            });

            this.initDateMode();

            var opts = this.options;
            if (typeof opts.startDate === 'object')
                this.startDate = moment(opts.startDate);

            if (typeof opts.endDate === 'object')
                this.endDate = moment(opts.endDate);

            if (typeof opts.minDate === 'object')
                this.minDate = moment(opts.minDate);

            if (typeof opts.maxDate === 'object')
                this.maxDate = moment(opts.maxDate);

            // sanity check for bad options
            if (this.minDate && this.startDate.isBefore(this.minDate))
                this.startDate = this.minDate.clone();

            // sanity check for bad options
            if (this.maxDate && this.endDate.isAfter(this.maxDate))
                this.endDate = this.maxDate.clone();


            if (typeof opts.onDateChanged == 'function') {
                this.onDateChanged = opts.onDateChanged;
            }

            this.changeDate(0);

            return this;
        },
        initDateMode: function() {
            var _this = this;
            XS.util.menuActive($('.date-chooser-mode > li'), {
                callback: function(menu){
                    var mode = $(menu).attr('data-value');
                    _this.onModeChanged(mode);
                }
            });
        },
        onModeChanged: function(mode) {
            this.mode = mode;
            if ('other' == this.mode) {
                this.btnControl.hide();
                this.initRangePicker();
            } else {
                this.destroyRangePicker();
                this.btnControl.show();
                if (this.mode == 'days') {
                    this.btnPrev.find('span').html('上一天');
                    this.btnNext.find('span').html('下一天');
                } else if (this.mode == 'months') {
                    this.btnPrev.find('span').html('上月');
                    this.btnNext.find('span').html('下月');
                }
                this.changeDate(0);
            }
        },
        initRangePicker: function(){
            var _this = this;
            this.rangePickerBlock.addClass('date-range-picker-on');
            this.rangePicker.daterangepicker({
                autoApply: true,
                opens: 'center',
                locale: $.fn.daterangepicker.locals['zh-CN'],
                dateLimit: { month: 1 },
                minDate: this.minDate,
                maxDate: this.maxDate
            }, function(start, end, label){
                _this.applyDate(start, end);
            });
        },
        destroyRangePicker: function(){
            this.rangePickerBlock.removeClass('date-range-picker-on');
        },
        changeDate: function(value) {
            var startDate, endDate;
            if (value == 0) {
                startDate = this.startDate;
            } else if (value > 0) {
                startDate = this.startDate.add(1, this.mode);
            } else {
                startDate = this.startDate.subtract(1, this.mode);
            }
            if ('months' == this.mode) {
                startDate = startDate.clone().startOf('month');
            }
            if (this.minDate && startDate.isBefore(this.minDate)) {
                startDate = this.minDate;
            }
            if (this.maxDate && startDate.isAfter(this.maxDate)) {
                startDate = this.maxDate.clone();
            }
            if ('months' == this.mode) {
                endDate = startDate.clone().endOf('month');
            } else {
                endDate = startDate.clone();
            }
            if (endDate.isBefore(startDate)) {
                endDate = startDate.clone();
            }
            if (this.maxDate && endDate.isAfter(this.maxDate)) {
                endDate = this.maxDate.clone();
            }
            if (this.dateLimit && startDate.clone().add(this.dateLimit).isBefore(endDate)) {
                endDate = startDate.clone().add(this.dateLimit);
            }
            this.applyDate(startDate, endDate);
        },
        applyDate: function(startDate, endDate){
            this.startDate = startDate;
            this.endDate = endDate;
            // console.log(startDate.format(this.dateFormat) + ' - ' + endDate.format(this.dateFormat));
            this.onDateChanged(startDate, endDate);
        }
    };

    $.extend(XS, {
        report: new Report(),
        dateChooser: function(){
            return new DateChooser({
                mode: 'days',
                onDateChanged: function(from, to) {
                    XS.report.loadHistoryReports(from, to, this.mode);
                },
                maxDate: moment()//.subtract(1, 'days')
            });
        }
    });

})(jQuery, window.XS);